addpath('../vlfeat-0.9.18/toolbox');
vl_setup;
clear;

N = 500;
experts = 20;
spammer = 0;
mali    = 0;
missRate = 0.5;
noiseRate = 0.2;
regul = 0.95;

X = randn(10, N);
Y = (rand(1, N) > 0.5);

% generate expert
E = repmat(Y, experts, 1);

% add noise
idx = randperm(numel(E));
idx = idx(1:floor(length(idx)*noiseRate));
E(idx) = ~E(idx);
clear idx;

% generate spammer
S = double(rand(spammer, N) > rand(spammer, N));

% make up whole data
D = cat(1, E, S);

% malocious work
M = repmat(~Y, mali, 1);
D = cat(1, D, M);

% add missing
Omega = zeros(size(D));
for i = 1:size(D, 1)
    idx = randperm(N);
    idx = idx(1:ceil(N*(1 - missRate)));
    Omega(i, idx) = 1;
end
Omega = logical(Omega);
clear i idx;

%% robust PMF
[U, V] = rpmf_l11(D.*Omega, 2, 10, 100, 1e-7);

[y] = majvote(U*V, Omega);
acc(1) = sum( (y>0.5) == Y)/numel(Y);

%% Major Voting -------------------------------------------------
[y] = majvote(D, Omega);
y = double(y > 0.5);
acc(2) = sum(y == Y)/numel(Y);

%% Raykar -------------------------------------------------------
[ y, alpha, beta ] = raykar( D.*Omega, Omega);

y = y > 0.5;
y = double(y);
acc(3) = sum(y' == Y)/numel(Y);
if(acc(3) < 0.5)
    acc(3) = 1 - acc(3);
end

clear y;

%% Robust PCA ---------------------------------------------------
D_rpca = D*2-1;
D_rpca = D_rpca.*Omega;
[L, C] = rpca_l21(D_rpca', Omega', regul);
% [L, C, iter] = rpca_l11(D_rpca', regul, 1e-6, 50);
L = L';
C = C';

close all;
figure;
imagesc(abs([L, C]));

score = sqrt(sum(C.^2, 2));
score = (score + 1)/min(score + 1);
score = 1./(score);
plot(score);

% [L, C] = rpca_l21(L, Omega, 0.15);
% 
% P = bsxfun(@times, L, score);
% P = mean(P, 1) > 0;

[~, idx] = vl_kmeans(score', 2);
C1 = mean(score(idx == 1));
C2 = mean(score(idx == 2));
if(C1 > C2)
    P = L(idx == 2, :);
else
    P = L(idx == 1, :);
end

% P = L;
P_pos =  double(P >  0.01);
P_neg = -double(P < -0.01);
P = P_pos + P_neg;
P = (sum(P, 1) > 0);

acc(4) = sum(P == Y)/numel(Y);

clear P_pos P_neg C1 C2 idx score D_rpca;